package com.seed.web;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.datasource.DataSourceDecipher;
import com.mybatisflex.core.keygen.KeyGenerators;
import com.mybatisflex.core.table.DynamicTableProcessor;
import com.mybatisflex.core.tenant.TenantFactory;
import com.mybatisflex.spring.boot.MyBatisFlexCustomizer;
import com.seed.application.EnableSeedApplication;
import com.seed.uaa.Uaa;
import com.seed.uaa.web.CheckLoginInterceptor;
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Slf4j
@SpringBootApplication
@EnableSeedApplication
public class SeedWebApplication implements MyBatisFlexCustomizer, WebMvcConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(SeedWebApplication.class);
    }

    public SeedWebApplication() {
        AuditManager.setAuditEnable(true);
        AuditManager.setMessageCollector(auditMessage ->
                log.info("{}, {}ms", auditMessage.getFullSql(), auditMessage.getElapsedTime())
        );
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new CheckLoginInterceptor());
        String[] anon = {"/app","/login","/doc.html", "/webjars/**", "/v3/**", "/favicon.ico", "/error"};
//        registry.addInterceptor(new SaInterceptor(handler -> {
//            StpKit.checkLogin();
//            if(handler instanceof HandlerMethod handlerMethod) {
//                Class<?> beanType = handlerMethod.getBeanType();
//                if(beanType == IndexController.class) return;
//
//                List<String> safeMethods = Arrays.asList("remove", "removeBatch");
//                String simpleName = beanType.getSimpleName();
//                String methodName = handlerMethod.getMethod().getName();
//                String name;
//                if(beanType == CrudController.class) {
//                    name = request.getParameter("tableName");
//                    if(StrKit.isBlank(name)) return;
//
//                    if(safeMethods.contains(methodName)) StpUtil.checkSafe();
//                } else {
//                    name = simpleName.substring(0, simpleName.indexOf("Controller"));
//                }
//
//                String moduleName = StrKit.toCamelCase(StrKit.lowerFirst(name));
//                System.out.println("=====================");
//                System.out.printf("%s===%s=====%s%n", serviceName, simpleName, methodName);
//                System.out.printf("%s:%s:%s%n", serviceName, moduleName, methodName);
//                StpUtil.checkPermission(String.format("%s:%s:%s", serviceName, moduleName, methodName));
//            }
//
//        })).addPathPatterns("/**").excludePathPatterns(anon);
    }

    @Override
    public void customize(FlexGlobalConfig globalConfig) {
        FlexGlobalConfig.KeyConfig keyConfig = new FlexGlobalConfig.KeyConfig();
        keyConfig.setKeyType(KeyType.Generator);
        keyConfig.setValue(KeyGenerators.flexId);
        keyConfig.setBefore(true);

        globalConfig.setKeyConfig(keyConfig);

        globalConfig.setTenantColumn("tenant_code");
    }

    @Bean
    public DynamicTableProcessor dynamicTableProcessor(){
        return tableName -> {
//            String tenantCode = webContext.getTenantCode();
//            String table = (StrUtil.isEmpty(tenantCode)? "": tenantCode + "_") + tableName;
//
//            log.info("当前数据源{}： ", tenantCode);
//            log.info("=======================查询表名{}:", table);
//
//            return table;
            return tableName;
        };
    }

    @Bean
    public TenantFactory tenantFactory(){
//        String tenantCode = webContext.getTenantCode();
//        log.info("租户编号：{}", tenantCode);
        String tenantCode = null;
        return () -> StrUtil.isEmpty(tenantCode) ? null : new Object[]{ tenantCode };
    }

    @Bean
    public DataSourceDecipher decipher(){
        return (property, value) -> {
            log.info("数据源属性,可以在这里加密：{}={}", property, value);
            return value;
        };
    }

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI().info(new Info().title("XXX平台接口")
                        .description("文档接口").version("v1.0.0")
                        .license(new License().name("Apache 2.0").url("https://github.com/macrozheng/mall-learning")))
                .externalDocs(new ExternalDocumentation().description("XXX管理后台文档")
                        .url("http://www.baidu.com"));
    }

    @Bean
    public GroupedOpenApi adminApi() {
        return GroupedOpenApi.builder().group("管理后台").pathsToMatch("/**").build();
    }
}